#include <disp_manager.h>
#include <stdio.h>
#include <string.h>

/* 管理底层的LCD,Web*/
static pDispOpr g_DispDevs = NULL;
static pDispOpr g_DispDefault = NULL;
static DispBuff g_tDispBuff;
static int line_width;	//每一行宽度
static int pixel_width;	//每个像素的宽度


void DrawTextInReginCentral(char *name, PRegion ptRegion, unsigned int dwColor)
{
	int iOriginX, iOriginY;
	FontBitMap tFontBitMap;
	int i = 0;
	int error = 0;
	RegionCartesian tRegionCar;
	/* 计算字符的外框 */
	GetStringRegionCar(name, &tRegionCar);
	/* 算出第一个字符的origin */
	iOriginX = ptRegion->iLeftUpX + (ptRegion->iWidth - tRegionCar.iWidth) / 2 - tRegionCar.iLeftUpX;
	iOriginY = ptRegion->iLeftUpY + (ptRegion->iHeight - tRegionCar.iHeight) / 2 + tRegionCar.iLeftUpY;

	while(name[i])
	{
		/* get bitmap */
		tFontBitMap.iCurOriginX = iOriginX;
		tFontBitMap.iCurOriginY = iOriginY;
		error = GetFontBitMap(name[i], &tFontBitMap);
		if(error != 0)
		{
			printf("GetFontBitMap error \n");
			return;
		}
		
		/* draw on buffer */
		DrawFontBitMap(&tFontBitMap, dwColor);

		/* flush to lcd/web */
		
		iOriginX = tFontBitMap.iNextOriginX;
		iOriginY = tFontBitMap.iNextOriginY;
		i++;
	}
}


void DrawFontBitMap(pFontBitMap ptFontBitMap, unsigned int dwColor)
{
	int  i, j, p, q;
	int x = ptFontBitMap->tRegion.iLeftUpX;
	int y = ptFontBitMap->tRegion.iLeftUpY;
	int  x_max = x + ptFontBitMap->tRegion.iWidth;
	int  y_max = y + ptFontBitMap->tRegion.iHeight;
	unsigned char *buffer = ptFontBitMap->punBuffer;
	int width = ptFontBitMap->tRegion.iWidth;
	//printf("x = %d, y = %d\n", x, y);

	for ( j = y, q = 0; j < y_max; j++, q++ )
	{
		for ( i = x, p = 0; i < x_max; i++, p++ )
		{
			if ( i < 0      || j < 0       ||
				i >= g_tDispBuff.iXres || j >= g_tDispBuff.iYres )
			continue;

			//image[j][i] |= bitmap->buffer[q * bitmap->width + p];
			if(buffer[q * width + p])
				PutPixel(i, j, dwColor);
		}
	}
}

void DrawRegion(PRegion ptRegion, unsigned int dwColor)
{
	int x = ptRegion->iLeftUpX;
	int y = ptRegion->iLeftUpY;
	int width = ptRegion->iWidth;
	int height = ptRegion->iHeight;

	int i, j;

	for(j = y; j < y + height; j++)
	{
		for(i = x; i < x + width; i++)
		{
			PutPixel(i, j, dwColor);
		}
	}
	
}



//描点函数
int PutPixel(int x, int y, unsigned int dwColor)
{
	//获取描点的位置
	unsigned char *pen_8 =  (unsigned char *)(g_tDispBuff.buff + y * line_width + x * pixel_width);
	unsigned short *pen_16;
	unsigned int *pen_32;

	unsigned int red, green, blue;
	
	pen_16 = (unsigned short *)pen_8;
	pen_32 = (unsigned int *)pen_8;

	switch(g_tDispBuff.iBpp)
	{
		case 8:
		{
			*pen_8 = dwColor;
			break;
		}
		case 16:
		{
			/* 565 */
			red   = (dwColor >> 16) & 0xff;
			green = (dwColor >> 8) & 0xff;
			blue  = (dwColor >> 0) & 0xff;
			dwColor = ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
			*pen_16 = dwColor;
			break;
		}
		case 32:
		{
			*pen_32 = dwColor;
			break;
		}
		default:
		{
			printf("can't surport %dbpp\n",g_tDispBuff.iBpp);
			return -1;
			break;
		}
	}
	return 0;
}

void RegisterDisplay(pDispOpr ptDispOpr)
{
	ptDispOpr->ptNext = g_DispDevs;
	g_DispDevs = ptDispOpr;
}

int SelectDefaultDisplay(char *name)
{
	pDispOpr pTmp = g_DispDevs;
	while(pTmp)
	{
		if(strcmp(name, pTmp->name) == 0)
		{
			g_DispDefault = pTmp;
			return 0;
		}
		pTmp = pTmp->ptNext;
	}

	return -1;
}

int InitDefaultDisplay(void)
{
	int ret;
	ret = g_DispDefault->DeviceInit();
	if(ret)
	{
		printf("DeviceInit error\n");
		return -1;
	}
	ret = g_DispDefault->GetBuffer(&g_tDispBuff);
	if(ret)
	{
		printf("GetBuffer error\n");
		return -1;
	}
	line_width  = g_tDispBuff.iXres * g_tDispBuff.iBpp / 8;
	pixel_width = g_tDispBuff.iBpp / 8;
	return 0;
}

pDispBuff GetDisplayBuffer(void)
{
	return &g_tDispBuff;
}

/*	将数据刷新到显存
 *	这个底层的函数中什么也没做，因为GetBuffer中映射的就是显存地址
 *	如果映射的是内存，就需要手动刷新到显存中
 *	因此这里进行统一
 */
int FlushDisplayRegion(PRegion ptRegion, pDispBuff ptDispBuff)
{
	return g_DispDefault->FlushRegion(ptRegion, ptDispBuff);
}


void DisplaySystemRegister(void)
{
	FrambufferRegister();
}
